<?php

require_once($_SERVER['DOCUMENT_ROOT'] . '/fatec-si/model/' . 'User.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/fatec-si/model/' . 'Escritorio.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/fatec-si/model/' . 'Client.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/fatec-si/model/' . 'ProcessoCliente.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/fatec-si/model/' . 'ProcessoUsuario.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/fatec-si/model/' . 'Evento.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/fatec-si/model/' . 'Processo.php');


class MySQLAdapter {

	protected $_config = array();
	protected $_link;
	protected $_result;

	/**
	 * Constructor
	 */
	public function __construct(array $config) {
		if (count($config) !== 4) {
			throw new InvalidArgumentException('Invalid number of connection parameters.');
		}
		$this->_config = $config;
	}

	/**
	 * Connect to MySQL
	 */
	public function connect() {
		// connect only once
		if ($this->_link === null) {
			list($host, $user, $password, $database) = $this->_config;
			if (!$this->_link = @mysqli_connect($host, $user, $password, $database)) {
				throw new RuntimeException('Error connecting to the server : ' . mysqli_connect_error());
			}
			unset($host, $user, $password, $database);
		}
		return $this->_link;
	}

	/**
	 * Execute the specified query
	 */
	public function query($query) {
		if (DEBUG)
			echo "QUERY -> $query";
		if (!is_string($query) || empty($query)) {
			throw new InvalidArgumentException('The specified query is not valid.');
		}
		// lazy connect to MySQL
		$this->connect();
		if (!$this->_result = mysqli_query($this->_link, $query)) {
			throw new RuntimeException('Error executing the specified query ' . $query . mysqli_error($this->_link));
		}
		return $this->_result;
	}

	/**
	 * Perform a SELECT statement
	 */
	public function select($table, $where = '', $fields = '*', $order = '', $limit = null, $offset = null) {

		$query = 'SELECT ' . $fields . ' FROM ' . $table
		. (($where) ? ' WHERE ' . $where : '')
		. (($limit) ? ' LIMIT ' . $limit : '')
		. (($offset && $limit) ? ' OFFSET ' . $offset : '')
		. (($order) ? ' ORDER BY ' . $order : '');
		$this->query($query);

		return $this->countRows();
	}

	public function fetchAll($class) {
		$reflector = new ReflectionClass($class);
		$result = array();
		$i = 0;
		while (($row = $this->fetch()) != false) {
			$properties = $reflector->getProperties();
			$a = new $class;
			foreach ($properties as $property) {

				$field = $property->getName();

				$a->{$field} = $row["$field"];
				;
			}
			$result[$i] = $a;
			$i++;
		}

		return $result;
	}

	public function fetchAllByFilter($class, array $filter) {
		$reflector = new ReflectionClass($class);

		$result = array();
		$i = 0;
		while (($row = $this->fetch()) != false) {
			$properties = $reflector->getProperties();

			$a = new $class;
			$val = array();

			foreach ($properties as $property) {
				$field = $property->getName();
				if (!in_array($field, $filter)) {
					$val[$field] = $row["$field"];
				}
			}
			$result[$i] = $val;
			$i++;
		}
		return $result;
	}

	/**
	 * Perform an INSERT statement
	 */
	public function insert($table, array $data) {
		$fields = implode(',', array_keys($data));
		$values = implode(',', array_map(array($this, 'quoteValue'), array_values($data)));
		$query = 'INSERT INTO ' . $table . ' (' . $fields . ') ' . ' VALUES (' . $values . ')';
		$this->query($query);
		return $this->getInsertId();
	}

	/**
	 * Perform an UPDATE statement
	 */
	public function update($table, array $data, $where = '') {
		$set = array();
		foreach ($data as $field => $value) {
			$set[] = $field . '=' . $this->quoteValue($value);
		}
		$set = implode(',', $set);
		$query = 'UPDATE ' . $table . ' SET ' . $set
		. (($where) ? ' WHERE ' . $where : '');
		$this->query($query);
		return $this->getAffectedRows();
	}

	/**
	 * Perform a DELETE statement
	 */
	public function delete($table, $where = '') {
		$query = 'DELETE FROM ' . $table
		. (($where) ? ' WHERE ' . $where : '');
		$this->query($query);
		return $this->getAffectedRows();
	}

	/**
	 * Escape the specified value
	 */
	public function quoteValue($value) {
		$this->connect();
		if ($value === null) {
			$value = 'NULL';
		} else if (!is_numeric($value)) {
			$value = "'" . mysqli_real_escape_string($this->_link, $value) . "'";
		}
		return $value;
	}

	/**
	 * Fetch a single row from the current result set (as an associative array)
	 */
	public function fetch() {
		if ($this->_result !== null) {
			if (($row = mysqli_fetch_array($this->_result, MYSQLI_ASSOC)) === false) {
				$this->freeResult();
			}
			return $row;
		}
		return false;
	}

	/**
	 * Get the insertion ID
	 */
	public function getInsertId() {
		return $this->_link !== null ? mysqli_insert_id($this->_link) : null;
	}

	/**
	 * Get the number of rows returned by the current result set
	 */
	public function countRows() {
		return $this->_result !== null ? mysqli_num_rows($this->_result) : 0;
	}

	/**
	 * Get the number of affected rows
	 */
	public function getAffectedRows() {
		return $this->_link !== null ? mysqli_affected_rows($this->_link) : 0;
	}

	/**
	 * Free up the current result set
	 */
	public function freeResult() {
		if ($this->_result === null) {
			return false;
		}
		mysqli_free_result($this->_result);
		return true;
	}

	/**
	 * Close explicitly the database connection
	 */
	public function disconnect() {
		if ($this->_link === null) {
			return false;
		}
		mysqli_close($this->_link);
		$this->_link = null;
		return true;
	}

	/**
	 * Close automatically the database connection when the instance of the class is destroyed
	 */
	public function __destruct() {
		$this->disconnect();
	}

	public function geraMD5($string) {
		return md5($string);
	}

	/* backup the db  */

	function backup() {
		$dir_backup = $_SERVER['DOCUMENT_ROOT'] . '/fatec-si/backup';
		// 		$this->cleanBackups($dir_backup);
		$this->createSQL($dir_backup);
	}

	function cleanBackups($dir) {
		/* Comando remover arquivos temporarios */
		/* WARNING: Esse comando pode causar danos no seu sistema operacional.
		 Remove (unlink) the FILE(s).
		-f, --force
		ignore nonexistent files, never prompt
		--version
		output version information and exit
		--preserve-root
		do not remove ‘/’ (default)
		*/
		$rm = "rm -fv --preserve-root {$dir}/*.sql";
		$this->execute($rm);
	}

	function createSQL($dir) {
		list($host, $user, $password, $database) = $this->_config;
		$file_name = NAME_FILE_BACKUP;
		$mysqldump = "mysqldump -elFq -u {$user} -p{$password} -h {$host} {$database} > {$dir}/{$file_name}";
		$this->execute($mysqldump);
	}

	/**
	 * Executa um comando via shell, caso não consigar executar o comando parar o script
	 * @param String $command, O comando que será executado
	 */
	function execute($command) {
		shell_exec($command);
	}

}

?>
